package com.mashibing.serviceverificationcode.service.impl;

import com.mashibing.internalcommon.constant.CommonStatusEnum;
import com.mashibing.internalcommon.constant.IdentityConstant;
import com.mashibing.internalcommon.constant.RedisKeyPrefixConstant;
import com.mashibing.internalcommon.dto.ResponseResult;
import com.mashibing.internalcommon.dto.serviceverificationcode.response.VerifyCodeResponse;
import com.mashibing.serviceverificationcode.service.VerifyCodeService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author gorkr
 * @date 2022/04/27 18:47
 **/
@Service
public class VerifyCodeServiceImpl implements VerifyCodeService {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Override
    public ResponseResult generate(int identity, String phoneNumber) {
        // todo: 校验 发送时限 三档验证 不能无限制发短信
        // checkSendCodeTimeLimit(phoneNumber);


        // 生成验证码  使用数学运算效率远高于字符串运算
        String code = String.valueOf((int) ((Math.random() * 9 + 1) * Math.pow(10, 5)));

        // 存入redis value 是什么
        String keyPre = generateKeyPreByIdentity(identity);
        String key = keyPre + phoneNumber;
        // 存入redis 2 分钟过期
        BoundValueOperations<String, String> codeRedis = redisTemplate.boundValueOps(key);

//        Boolean aBoolean = codeRedis.setIfAbsent(code);
//        if (aBoolean){
//            codeRedis.expire(2,TimeUnit.MINUTES);
//        }
//        codeRedis.expire(2,TimeUnit.MINUTES);

        // 原子性操作 防止打断 使值永存
        codeRedis.set(code,2, TimeUnit.MINUTES);



        // 返回
        VerifyCodeResponse result = new VerifyCodeResponse();
        result.setCode(code);

        // 设置redis的过期时间的时候要原子 万一服务器挂了 key就永久了

        return ResponseResult.success(result);
    }

    @Override
    public ResponseResult verify(int identity, String phoneNumber, String code) {
        // 三档验证

        // 生成redis key
        String keyPre = generateKeyPreByIdentity(identity);
        String key = keyPre + phoneNumber;

        BoundValueOperations<String, String> codeRedis = redisTemplate.boundValueOps(key);
        String redisCode = codeRedis.get();

        if(StringUtils.isNotBlank(code)
            && StringUtils.isNotBlank(redisCode)
            && code.trim().equals(redisCode)){
            return ResponseResult.success("");
        }else {
            return ResponseResult.fail(CommonStatusEnum.VERIFY_CODE_ERROR.getCode(),CommonStatusEnum.VERIFY_CODE_ERROR.getValue());
        }

    }


    /**
     * 根据身份类型生成对应的缓存key
     * @param identity
     * @return
     */
    private String generateKeyPreByIdentity(int identity) {
        String keyPre = "";
        if(identity == IdentityConstant.PASSENGER){
            keyPre = RedisKeyPrefixConstant.PASSENGER_LOGIN_CODE_KEY_PRE;
        }else if(identity == IdentityConstant.DRIVER){
            keyPre = RedisKeyPrefixConstant.DRIVER_LOGIN_CODE_KEY_PRE;
        }
        return keyPre;
    }
}
    